package com.litchi.utils;

import com.codepoetics.protonpack.StreamUtils;
import com.litchi.entity.Lottery;
import com.litchi.entity.Match;
import org.apache.commons.lang3.StringUtils;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

/**
 * Created by huash on 2016/5/8.
 */
public class LotteryUtils {

    public static double winProbabilityOfMatch(@NotNull Match match) {
        double d = returnRateOfMatch(match);
        return d / match.getWinOdds();
    }

    public static double tieProbabilityOfMatch(Match match) {
        double d = returnRateOfMatch(match);
        return d / match.getTieOdds();
    }

    public static double lostProbabilityOfMatch(@NotNull Match match) {
        double d = returnRateOfMatch(match);
        return d / match.getLostOdds();
    }

    public static boolean isMatchFinished(@NotNull Match match) {
        return StringUtils.isNotBlank(match.getScore()) && match.getScore().matches("\\s*\\d+\\s*:\\s*\\d+\\s*");
    }

    public static boolean isLotteryFinished(@NotNull Lottery lottery) {
        return lottery.getMatchList().stream().anyMatch(m -> !isMatchFinished(m));
    }

    public static void fillPropertiesOfMatch(@NotNull Match match) {
        double d = returnRateOfMatch(match);
        match.setWinProbability(d / match.getWinOdds());
        match.setTieProbability(d / match.getTieOdds());
        match.setLostProbability(d / match.getLostOdds());
        match.setFinished(isMatchFinished(match));
    }

    public static void fillPropertiesOfLottery(@NotNull Lottery lottery) {
        lottery.setFinished(isLotteryFinished(lottery));
    }

    public static double probabilityOfBet(@NotNull Lottery lottery, @NotNull String bet) {
        String[] bets = bet.split(",");
        ArrayList<Match> matches = new ArrayList<>(lottery.getMatchList());
        matches.sort(new Comparator<Match>() {
            @Override
            public int compare(Match o1, Match o2) {
                return o1.getOrder() - o2.getOrder();
            }
        });
        double p = 1.0;
        for (int i = 0; i < bets.length; i++) {
            String b = bets[i];
            Match m = matches.get(i);
            if (b.equalsIgnoreCase("0")) {
                p *= m.getLostProbability();
            } else if (b.equalsIgnoreCase("1")) {
                p *= m.getTieProbability();
            } else if (b.equalsIgnoreCase("3")) {
                p *= m.getLostProbability();
            }
        }

        return p;
    }

    private static double returnRateOfMatch(@NotNull Match match) {
        return match.getWinOdds() * match.getLostOdds() * match.getTieOdds() / (match.getWinOdds() * match.getTieOdds()
                + match.getTieOdds() * match.getLostOdds() + match.getWinOdds() * match.getLostOdds());
    }
}
